package ui

import (
	"fmt"
	"os"
	"path/filepath"
	"strconv"
	"strings"

	"x-admin-generator/internal/config"
	"x-admin-generator/internal/database"
	"x-admin-generator/internal/generator"
	"x-admin-generator/internal/types"
)

// CheckTempDirectoryHasFiles 检查临时目录是否有文件
func CheckTempDirectoryHasFiles(tempDir string) (bool, error) {
	hasFiles := false
	err := filepath.Walk(tempDir, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		if !info.IsDir() {
			hasFiles = true
			return filepath.SkipDir // 找到文件就可以停止遍历
		}
		return nil
	})
	return hasFiles, err
}

// ShowCopyPreview 显示复制预览
func ShowCopyPreview(tempDir string) {
	cfg := config.GetConfig()
	projectRoot := cfg.Paths.ProjectRoot

	err := filepath.Walk(tempDir, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}

		if info.IsDir() {
			return nil
		}

		// 计算相对路径
		relPath, _ := filepath.Rel(tempDir, path)

		// 计算目标路径
		targetPath := filepath.Join(projectRoot, relPath)

		// 检查目标文件是否已存在
		status := "新建"
		if _, err := os.Stat(targetPath); err == nil {
			status = "覆盖"
		}

		fmt.Printf("  %s %s -> %s\n", status, relPath, targetPath)
		return nil
	})

	if err != nil {
		fmt.Printf("❌ 预览文件失败: %v\n", err)
	}
}

// CopyGeneratedFilesToProject 复制生成的文件到项目
func CopyGeneratedFilesToProject(tempDir string) error {
	cfg := config.GetConfig()
	projectRoot := cfg.Paths.ProjectRoot
	copiedCount := 0

	err := filepath.Walk(tempDir, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}

		if info.IsDir() {
			return nil
		}

		// 计算相对路径和目标路径
		relPath, _ := filepath.Rel(tempDir, path)
		targetPath := filepath.Join(projectRoot, relPath)

		// 创建目标目录
		targetDir := filepath.Dir(targetPath)
		if err := os.MkdirAll(targetDir, 0755); err != nil {
			return fmt.Errorf("创建目录失败 %s: %w", targetDir, err)
		}

		// 复制文件
		if err := generator.CopyFile(path, targetPath); err != nil {
			return fmt.Errorf("复制文件失败 %s -> %s: %w", path, targetPath, err)
		}

		fmt.Printf("✓ 复制: %s\n", relPath)
		copiedCount++
		return nil
	})

	if err != nil {
		return err
	}

	fmt.Printf("\n📊 总共复制了 %d 个文件\n", copiedCount)
	return nil
}

// GenerateModelConfigFromTable 从数据库表生成模型配置
func GenerateModelConfigFromTable(tableInfo *types.TableInfo) *types.ModelConfig {
	// 生成模型名称（去掉表前缀，转为驼峰命名）
	modelName := GenerateModelName(tableInfo.Name)

	// 生成字段配置
	var fields []types.Field
	for _, col := range tableInfo.Columns {
		field := types.Field{
			Name:     col.Name,
			Type:     MapDatabaseTypeToGoType(col.Type),
			Required: !col.Nullable && col.Default.String == "",
			Comment:  col.Comment,
		}

		// 设置主键
		if col.Key == "PRI" {
			field.Primary = true
		}

		// 设置唯一键
		if col.Key == "UNI" {
			field.Unique = true
		}

		// 设置字符串长度
		if field.Type == "string" {
			field.Size = ExtractStringSize(col.Type)
		}

		// 设置默认值
		if col.Default.Valid && col.Default.String != "" {
			field.Default = col.Default.String
		}

		fields = append(fields, field)
	}

	// 生成注释
	comment := tableInfo.Comment
	if comment == "" {
		comment = modelName + "管理"
	}

	return &types.ModelConfig{
		Model: types.Model{
			Name:    modelName,
			Table:   tableInfo.Name,
			Comment: comment,
			Fields:  fields,
		},
	}
}

// GenerateModelName 生成模型名称
func GenerateModelName(tableName string) string {
	// 移除常见的表前缀
	prefixes := []string{"t_", "tb_", "tbl_"}
	for _, prefix := range prefixes {
		if strings.HasPrefix(tableName, prefix) {
			tableName = tableName[len(prefix):]
			break
		}
	}

	// 转为驼峰命名
	parts := strings.Split(tableName, "_")
	var result strings.Builder
	for _, part := range parts {
		if len(part) > 0 {
			result.WriteString(strings.ToUpper(part[:1]))
			if len(part) > 1 {
				result.WriteString(strings.ToLower(part[1:]))
			}
		}
	}

	return result.String()
}

// MapDatabaseTypeToGoType 映射数据库类型到Go类型
func MapDatabaseTypeToGoType(dbType string) string {
	// 转为小写并提取基础类型
	dbType = strings.ToLower(dbType)

	// 整数类型
	if strings.Contains(dbType, "int") {
		if strings.Contains(dbType, "unsigned") || strings.Contains(dbType, "bigint") {
			return "uint"
		}
		return "int"
	}

	// 浮点数类型
	if strings.Contains(dbType, "float") || strings.Contains(dbType, "double") || strings.Contains(dbType, "decimal") {
		return "float64"
	}

	// 布尔类型
	if strings.Contains(dbType, "bool") || strings.Contains(dbType, "tinyint(1)") {
		return "bool"
	}

	// 时间类型
	if strings.Contains(dbType, "time") || strings.Contains(dbType, "date") {
		return "time"
	}

	// 默认为字符串类型
	return "string"
}

// ExtractStringSize 提取字符串长度
func ExtractStringSize(dbType string) int {
	// 查找括号中的数字
	start := strings.Index(dbType, "(")
	end := strings.Index(dbType, ")")

	if start != -1 && end != -1 && end > start {
		sizeStr := dbType[start+1 : end]
		if size, err := strconv.Atoi(sizeStr); err == nil {
			return size
		}
	}

	// 默认长度
	if strings.Contains(dbType, "text") {
		return 1000
	}

	return 255
}

// ConvertTableToModelConfig 将表信息转换为模型配置
func ConvertTableToModelConfig(tableInfo *types.TableInfo) *types.ModelConfig {
	// 生成模型名称（首字母大写的驼峰命名）
	modelName := config.ToCamelCase(tableInfo.Name)
	if len(modelName) > 0 {
		modelName = strings.ToUpper(modelName[:1]) + modelName[1:]
	}

	modelConfig := &types.ModelConfig{
		Model: types.Model{
			Name:    modelName,
			Table:   tableInfo.Name,
			Comment: tableInfo.Comment,
			Fields:  make([]types.Field, 0, len(tableInfo.Columns)),
		},
	}

	// 转换字段
	for _, column := range tableInfo.Columns {
		var defaultValue interface{}
		if column.Default.Valid {
			defaultValue = column.Default.String
		}

		field := types.Field{
			Name:     column.Name,
			Type:     database.ConvertMySQLTypeToGo(column.Type),
			Primary:  column.Key == "PRI",
			Required: !column.Nullable && column.Key != "PRI",
			Default:  defaultValue,
			Comment:  column.Comment,
		}

		modelConfig.Model.Fields = append(modelConfig.Model.Fields, field)
	}

	return modelConfig
}